package com.example.udpmulticastdemo;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import org.json.JSONException;
import org.json.JSONObject;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @ author : lgh_ai
 * @ e-mail : lgh_developer@163.com
 * @ date   : 19-1-14 下午4:49
 * @ desc   : 字节转换工具类
 */
public class BytesUtil {


//    public static String getFrame(byte[] bytes) {
//        StringBuffer stringBuffer = new StringBuffer();
//        for (int i = 0; i < bytes.length; i++) {
//            String hex = Integer.toHexString(bytes[i]);
//            if (hex.length() == 1) {
//                stringBuffer.append("0" + hex);
//            } else {
//                stringBuffer.append(hex);
//            }
//            if (i > 20) {
//                break;
//            }
//        }
//        String dataStr = stringBuffer.toString();
//        String spsStr = dataStr.substring(8, 10);
////        Log.e("Screen -> ", dataStr);
//        return spsStr;
//    }

    //检查帧类型，i帧为5,sps为7,pps为8
    public static boolean checkFrameType(byte[] data,int type) {
        if( data == null || data.length < 5) {
            return false;
        }
        if (data[0] != 0x0 || data[1] != 0x0 || data[2] != 0x0 || data[3] != 0x1) {
            return false;
        }
        return (data[4] & 0x1F) == type;
    }

    //判断一个byte数值在另外一个byte数组中对应的游标值，指定开始的游标和结束的游标位置
    public static int getByteIndexOf(byte[] sources, byte[] src, int startIndex, int endIndex) {
        if (sources == null || src == null || sources.length == 0 || src.length == 0) {
            return -1;
        }
        if (endIndex > sources.length) {
            endIndex = sources.length;
        }
        int i, j;
        for (i = startIndex; i < endIndex; i++) {
            if (sources[i] == src[0] && i + src.length < endIndex) {
                for (j = 1; j < src.length; j++) {
                    if (sources[i + j] != src[j]) {
                        break;
                    }
                }

                if (j == src.length) {
                    return i;
                }
            }
        }
        return -1;
    }


//    public static byte[] getSPSFrame(byte[] data) {
//        int startIndex = 0;
//        int totalLength = data.length;
//        byte[] res = null;
////        byte[] prefix = {0x00, 0x00, 0x00, 0x01,0x25};
//        byte[] prefix = {0x00, 0x00, 0x00, 0x01, 0x21};
//
//        byte[] prefix = {0x00, 0x00, 0x00, 0x01,0x67};
//
//        byte[] prefix2 = {0x00, 0x00, 0x00, 0x01};
//
//
//        startIndex = getByteIndexOf(data, prefix, startIndex, totalLength);
//        int endIndex = getByteIndexOf(data, prefix, startIndex + prefix.length, totalLength);
//        if (startIndex != -1 && endIndex != -1) {
//            res = Arrays.copyOfRange(data, startIndex, endIndex);
//        }
//
//        Log.e("---------", "-------------------startIndex:" + startIndex);
//
//        return res;
//    }



    public static ArrayList<byte[]> splitIFrames(byte[] data) {
        int startIndex = 0;
        int endIndex = 0;
        int totalLength = data.length;
        ArrayList<byte[]> res = new ArrayList<>();
        byte[] prefix = {0x00, 0x00, 0x01};

        do {
            startIndex = getByteIndexOf(data, prefix, startIndex, totalLength);
            endIndex = getByteIndexOf(data, prefix, startIndex + prefix.length, totalLength);
            if (startIndex != -1 && endIndex != -1) {
                res.add(Arrays.copyOfRange(data, startIndex, endIndex));
                startIndex = endIndex;
            }
        } while (startIndex != -1 && endIndex != -1);


        return res;
    }


    /**
     * 注释：short到字节数组的转换！
     *
     * @param temp temp
     * @return
     */
    public static byte[] shortToByte(int temp) {
        byte[] b = new byte[2];
        for (int i = 0; i < b.length; i++) {
            b[i] = Integer.valueOf(temp & 0xff).byteValue();
            //将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return b;
    }


    /**
     * 注释：int到字节数组的转换！
     *
     * @param number
     * @return
     */
    public static byte[] intToByte(int number) {
        int temp = number;
        byte[] b = new byte[4];
        for (int i = 0; i < b.length; i++) {
            b[i] = Integer.valueOf(temp & 0xff).byteValue();
            //将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return b;
    }

    /**
     * 注释：long到字节数组的转换！
     *
     * @param number
     * @return
     */
    public static byte[] longToByte(long number) {
        long temp = number;
        byte[] bytes = new byte[8];
        for (int i = 0; i < bytes.length; i++) {
            bytes[i] = new Long(temp & 0xff).byteValue();//将最低位保存在最低位
            temp = temp >> 8; // 向右移8位
        }
        return bytes;
    }

    /**
     * 注释：float到字节数组的转换！
     *
     * @param number
     * @return
     */
    public static byte[] floatToByte(float number) {
        int intBits = Float.floatToIntBits(number);
        return intToByte(intBits);
    }

    /**
     * 注释：double到字节数组的转换！
     *
     * @param number
     * @return
     */
    public static byte[] doubleToByte(double number) {
        long intBits = Double.doubleToLongBits(number);
        return longToByte(intBits);
    }

    /**
     * 注释：多媒体分享生成ulSessionId
     * sessionid =  (userid << 32) | (index ++);
     *
     * @param userId 用户id
     * @param index 下标
     * @return
     */
    public static long generateulSessionId(int userId, int index) {
        byte[] byteNum ;
        byte[] userByte = intToByte(userId);
        byte[] indexByte = intToByte(index);
        /**
         * byte[0]代表最低位，二进制表示法
         */
        byteNum = new byte[]{indexByte[0], indexByte[1], indexByte[2], indexByte[3], userByte[0], userByte[1], userByte[2], userByte[3]};
        return byteToLong(byteNum);
    }

    /**
     * 小端byte转大端int
     * 注释：字节数组到int的转换！
     *
     * @param
     * @return
     */
    public static int byteToInt(byte[] b) {
        int s;
        int s0 = b[0] & 0xff;// 最低位
        int s1 = b[1] & 0xff;
        int s2 = b[2] & 0xff;
        int s3 = b[3] & 0xff;
        s3 <<= 24;
        s2 <<= 16;
        s1 <<= 8;
        s = s0 | s1 | s2 | s3;
        return s;
    }


    /**
     * 注释：字节数组到short的转换！
     *
     * @param b b
     * @return
     */
    public static short byteToShort(byte[] b) {
        short s;
        short s0 = (short) (b[0] & 0xff);// 最低位
        short s1 = (short) (b[1] & 0xff);
        s1 <<= 8;
        s = (short) (s0 | s1);
        return s;
    }

    /**
     * 注释：字节数组到long的转换！
     *
     * @param byteNum byteNum
     * @return num
     */
    public static long byteToLong(byte[] byteNum) {
        long s = 0;
        long s0 = byteNum[0] & 0xff;// 最低位
        long s1 = byteNum[1] & 0xff;
        long s2 = byteNum[2] & 0xff;
        long s3 = byteNum[3] & 0xff;
        long s4 = byteNum[4] & 0xff;// 最低位
        long s5 = byteNum[5] & 0xff;
        long s6 = byteNum[6] & 0xff;
        long s7 = byteNum[7] & 0xff;

        // s0不变
        s1 <<= 8;
        s2 <<= 16;
        s3 <<= 24;
        s4 <<= 8 * 4;
        s5 <<= 8 * 5;
        s6 <<= 8 * 6;
        s7 <<= 8 * 7;
        s = s0 | s1 | s2 | s3 | s4 | s5 | s6 | s7;
        return s;
    }

    /**
     * 注释：字节数组到Float的转换！
     *
     * @param byteNum byteNum
     * @return num
     */
    public static float byteToFloat(byte[] byteNum) {
        return Float.intBitsToFloat(byteToInt(byteNum));
    }


    /**
     * 注释：字节数组到Float的转换！
     *
     * @param byteNum byteNum
     * @return num
     */
    public static double byteToDouble(byte[] byteNum) {
        long l = byteToLong(byteNum);
        return Double.longBitsToDouble(l);
    }

    /**
     * 注释：字节数组到Bitmap的转换！
     *
     * @param byteNum byteNum
     * @return bitmap
     */
    public static Bitmap byteToBitmap(byte[] byteNum) {
        if (byteNum.length != 0){
            Bitmap bitmap = BitmapFactory.decodeByteArray(byteNum, 0, byteNum.length);
            return bitmap;
        }else {
            return null;
        }
    }

    /**
     * 将bytes数据转化成iSessionId
     * @param data
     * @return
     */
    public int[] byteToulSessionId(byte[] data){
        if (data != null) {
            /** 低32位:index++ */
            byte[] highBytes = new byte[]{data[0], data[1], data[2], data[3]};
            /** 高32位：userId */
            byte[] lowByttes = new byte[]{data[4], data[5], data[6], data[7]};

            return new int[]{byteToInt(highBytes), byteToInt(lowByttes)};
        }
        return null;
    }

    /**
     * 将bytes数据转化成iSessionId
     * @param data
     * @return
     */
    public int[] byteToGeId(byte[] data){
        if (data != null) {
            /** 低32位:index++ */
            byte[] highBytes = new byte[]{data[0], data[1]};
            /** 高32位：TimeStamp && 0xFFFF */
            byte[] lowByttes = new byte[]{data[2], data[3]};

            return new int[]{byteToShort(highBytes), byteToShort(lowByttes)};
        }
        return null;
    }


    /**
     * 将画笔标记转成服务器<增删查改>数据操作action code
     * @param styleTag
     * @return
     */
    private static int styleTagToAction(String styleTag){
        int action = 0;
        switch (styleTag){
            case "l":
            case "o":
            case "p":
            case "r":
            case "t":
                action = 1;
                break;
            case "bg":
                action = 2;
                break;
            case "e":    /** 将e放在上层处理，这里只处理绘制 */
                action = 3;
                break;
        }
        return action;
    }

    /**
     * 转化画笔类型
     * @param styleTag
     * @return
     */
    public static int styleTagToType(String styleTag) {
        int type = 0;
        switch (styleTag){
            case "l":
                type = 1;
                break;
            case "r":
                type = 3;
                break;
            case "o":
                type = 5;
                break;
            case "t":
                type = 6;
                break;
            case "e":
                type = 7;
                break;
            case "bg":
                type = 8;
                break;
            case "p":
                type = 10;
                break;
        }
        return type;
    }

    /**
     * 转化画笔类型成attr.styleTag
     * @param type
     * @return
     */
    private static String typeToStyleTag(int type) {
        String styleTag = "";
        switch (type){
            case 1:
                styleTag = "l";
                break;
            case 3:
            case 4:
                styleTag = "r";
                break;
            case 5:
                styleTag = "o";
                break;
            case 6:
                styleTag = "t";
                break;
            case 7:
                styleTag = "e";
                break;
            case 8:
                styleTag = "bg";
                break;
            case 2:
            case 10:
                styleTag = "p";
                break;
        }
        return styleTag;
    }

    private static int brushTypeBooleanToInt(boolean isFill) {
        return isFill ? 1 : 0;
    }

    private static boolean brushTypeIntToBoolean(int isFill) {
        return isFill == 1 ? true : false;
    }

    //   END  ////////////////////////////////////

    /**
     * 合并byte数组
     *
     * @param bytes1
     * @param bytes2
     * @return 合并结果
     */
    public static byte[] mergeByte(byte[] bytes1, byte[] bytes2) {
        byte[] result = new byte[bytes1.length+bytes2.length];
        System.arraycopy(bytes1, 0, result, 0, bytes1.length);
        System.arraycopy(bytes2, 0, result, bytes1.length, bytes2.length);
        return result;
    }


    /**
     * 截取byte数组, 不改变原数组
     * @param datas 原数组
     * @param offset 偏差值（索引）
     * @param length 长度
     * @return 截取后的数组
     */
    public static byte[] subByte(byte[] datas, int offset, int length) {
        byte[] result = new byte[length];
        System.arraycopy(datas, offset, result, 0, length);
        return result;
    }

}
